package com.educatioin.manage.web.productorder.service;

import com.educatioin.commons.exceptions.ServiceException;
import com.educatioin.commons.util.AjaxResult;
import com.educatioin.manage.constant.OrderStatus;
import com.educatioin.manage.web.productorder.po.ProductOrderPo;
import com.educatioin.manage.web.productorder.repository.ProductOrderRepository;
import com.educatioin.manage.web.productorder.request.ListOrderReq;
import com.educatioin.manage.web.productorder.request.ModifyOrderReq;
import com.educatioin.manage.web.productorder.response.ListOrderRsp;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.Optional;

/**
 * Created by zhangchen on 2018/4/19.
 */
@Service
public class ProductOrderService {

    @Resource
    private ProductOrderRepository productOrderRepository;

    public ListOrderRsp list(ListOrderReq req) {
        if(null == req.getPage() || req.getPage() <= 0
                || null == req.getLimit() || req.getLimit() <= 0){
            throw new ServiceException("分页查询错误！");
        }

        int page = req.getPage();
        if(page > 0) {
            page = page -1;
        }

        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageRequest = new PageRequest(page, req.getLimit(), sort);

        Page<ProductOrderPo> retPage = productOrderRepository.findAll((root, query, cb) -> {
            List<Predicate> predicates = Lists.newArrayList();
            if(StringUtils.isNoneBlank(req.getGroupName())) {
                predicates.add(cb.and(cb.equal(root.get("groupName"), req.getGroupName())));
            }
            if(StringUtils.isNoneBlank(req.getProductName())) {
                predicates.add(cb.and(cb.equal(root.get("productName"), req.getProductName())));
            }
            if(StringUtils.isNoneBlank(req.getPhone())) {
                predicates.add(cb.and(cb.equal(root.get("phone"), req.getPhone())));
            }
            if(req.getOrderStatus() != null) {
                predicates.add(cb.and(cb.equal(root.get("orderStatus"), OrderStatus.valueOf(req.getOrderStatus()).name())));
            }
            if(req.getProductType() != null) {
                predicates.add(cb.and(cb.equal(root.get("productType"), req.getProductType())));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        }, pageRequest);

        ListOrderRsp rsp = new ListOrderRsp();
        rsp.setCount((int) retPage.getTotalElements());
        rsp.setData(retPage.getContent());
        rsp.setReturnCode(ListOrderRsp.RETURN_SUCCESS_CODE);
        return rsp;
    }

    @Transactional(rollbackFor = Exception.class)
    public void modify(ModifyOrderReq req) {
        ProductOrderPo order = productOrderRepository.findOne(req.getId());
        Optional.ofNullable(req.getAddress()).ifPresent(order::setAddress);
        Optional.ofNullable(req.getAge()).ifPresent(order::setAge);
        Optional.ofNullable(req.getApplicantName()).ifPresent(order::setApplicantName);
        Optional.ofNullable(req.getClazz()).ifPresent(order::setClazz);
        Optional.ofNullable(req.getGrade()).ifPresent(order::setGrade);
        Optional.ofNullable(req.getGroupName()).ifPresent(order::setGroupName);
        Optional.ofNullable(req.getIdCard()).ifPresent(order::setIdCard);
        Optional.ofNullable(req.getOrderCode()).ifPresent(order::setOrderCode);
        Optional.ofNullable(req.getOrderStatus()).ifPresent(order::setOrderStatus);
        Optional.ofNullable(req.getPhone()).ifPresent(order::setPhone);
        Optional.ofNullable(req.getEmail()).ifPresent(order::setEmail);
        Optional.ofNullable(req.getPrepayId()).ifPresent(order::setPrepayId);
        Optional.ofNullable(req.getProductCode()).ifPresent(order::setProductCode);
        Optional.ofNullable(req.getProductDeposit()).ifPresent(order::setProductDeposit);
        Optional.ofNullable(req.getProductName()).ifPresent(order::setProductName);
        Optional.ofNullable(req.getRecommenderCode()).ifPresent(order::setRecommenderCode);
        Optional.ofNullable(req.getProductName()).ifPresent(order::setProductName);
        Optional.ofNullable(req.getProductImage()).ifPresent(order::setProductImage);

        order.setUpdateTime(System.currentTimeMillis());

        productOrderRepository.save(order);
    }

    @Transactional(rollbackFor = Exception.class)
    public AjaxResult close(Long id) {
        AjaxResult result = new AjaxResult<>();
        ProductOrderPo order = productOrderRepository.findOne(id);
        if (!order.getOrderStatus().equals(OrderStatus.UN_PAYED.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("只有未付款订单才可以删除");
        }
        if (order.getOrderStatus().equals(OrderStatus.CLOSED.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("订单已关闭");
        }
        order.setOrderStatus(OrderStatus.CLOSED.name());
        productOrderRepository.save(order);
        result.setCode(AjaxResult.SUCCESS_CODE);
        result.setMsg("设置成功");
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public AjaxResult payAll(Long id) {
        AjaxResult result = new AjaxResult<>();
        ProductOrderPo order = productOrderRepository.findOne(id);
        if (!order.getOrderStatus().equals(OrderStatus.ORDERED.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("只有已报名订单才可以设置");
        }
        if (order.getOrderStatus().equals(OrderStatus.PAYED.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("订单已付款");
        }
        order.setOrderStatus(OrderStatus.PAYED.name());
        productOrderRepository.save(order);
        result.setCode(AjaxResult.SUCCESS_CODE);
        result.setMsg("设置成功");
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public AjaxResult complete(Long id) {
        AjaxResult result = new AjaxResult<>();
        ProductOrderPo order = productOrderRepository.findOne(id);
        if (!order.getOrderStatus().equals(OrderStatus.PAYED.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("只有已付款订单才可以设置");
        }
        if (order.getOrderStatus().equals(OrderStatus.COMPLETE.name())) {
            result.setCode(AjaxResult.ERROR_CODE);
            result.setMsg("订单已完成");
        }
        order.setOrderStatus(OrderStatus.COMPLETE.name());
        productOrderRepository.save(order);
        productOrderRepository.save(order);
        result.setCode(AjaxResult.SUCCESS_CODE);
        result.setMsg("设置成功");
        return  result;
    }

    public ProductOrderPo findById(Long id) {
        return productOrderRepository.findOne(id);
    }
}